﻿using Clients;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication.Certificate;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpOverrides;

namespace SampleApi
{
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();

            services.AddCors();
            services.AddDistributedMemoryCache();

            services.AddAuthentication("token")
                .AddJwtBearer("token", options =>
                {
                    options.Authority = Constants.Authority;
                    options.TokenValidationParameters.ValidateAudience = false;
                    options.TokenValidationParameters.ValidTypes = new[] { "at+jwt" };
                });

            services.AddAuthorization(options => {
                options.AddPolicy("scope", policy => {
                    policy.AddAuthenticationSchemes("token")
                        .RequireAuthenticatedUser()
                        .RequireClaim("scope", "scope1");
                });
            });

            //    .AddIdentityServerAuthentication("token", options =>
            //    {
            //        options.Authority = Constants.Authority;

            //        // enable for MTLS scenarios
            //        // options.Authority = Constants.AuthorityMtls;

            //        options.ApiName = "api1";
            //        options.ApiSecret = "secret";

            //        options.JwtBearerEvents = new Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerEvents
            //        {
            //            OnTokenValidated = e =>
            //            {
            //                var jwt = e.SecurityToken as JwtSecurityToken;
            //                var type = jwt.Header.Typ;

            //                if (!string.Equals(type, "at+jwt", StringComparison.Ordinal))
            //                {
            //                    e.Fail("JWT is not an access token");
            //                }

            //                return Task.CompletedTask;
            //            }
            //        };
            //    })
            //    .AddCertificate(options =>
            //    {
            //        options.AllowedCertificateTypes = CertificateTypes.All;
            //    });

            //// enable for MTLS scenarios
            ////services.AddCertificateForwarding(options =>
            ////{
            ////    options.CertificateHeader = "X-SSL-CERT";

            ////    options.HeaderConverter = (headerValue) =>
            ////    {
            ////        X509Certificate2 clientCertificate = null;

            ////        if (!string.IsNullOrWhiteSpace(headerValue))
            ////        {
            ////            byte[] bytes = Encoding.UTF8.GetBytes(Uri.UnescapeDataString(headerValue));
            ////            clientCertificate = new X509Certificate2(bytes);
            ////        }

            ////        return clientCertificate;
            ////    };
            ////});
        }

        public void Configure(IApplicationBuilder app)
        {
            // enable for MTLS scenarios
            //app.UseForwardedHeaders(new ForwardedHeadersOptions
            //{
            //    ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
            //});

            //app.UseCertificateForwarding();

            app.UseCors(policy =>
            {
                policy.WithOrigins(
                    "https://localhost:44300");

                policy.AllowAnyHeader();
                policy.AllowAnyMethod();
                policy.WithExposedHeaders("WWW-Authenticate");
            });

            app.UseRouting();
            app.UseAuthentication();

            // enable for MTLS scenarios
            //app.UseConfirmationValidation(new ConfirmationValidationMiddlewareOptions
            //{
            //    CertificateSchemeName = CertificateAuthenticationDefaults.AuthenticationScheme,
            //    JwtBearerSchemeName = "token"
            //});

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers()
                    .RequireAuthorization("scope");
            });
        }
    }
}